package conceptualization;

import java.util.*;
import java.io.*;

public class Parser {
	private String instancePath = "pro_typicality" + File.separator + "ProbaseInstance_Filtered.ltf";
	private String conceptPath = "pro_typicality" + File.separator + "ProbaseClass_Filtered.ltf";
	private String typicalPath = "pro_typicality" + File.separator + "AllClassesForInstance.ltf";
	
	HashMap<String, Integer> conceptList;
	HashMap<String, Integer> instanceMap;
	HashMap<Integer, String> typical;
	
	public Parser() { 
		conceptList = new HashMap<String, Integer>();
		instanceMap = new HashMap<String, Integer>();
		typical = new HashMap<Integer, String>();
	}
	public Parser(String insPath, String conPath, String typPath) {
		instancePath = insPath;
		conceptPath = conPath;
		typicalPath = typPath;
	}
	
	public boolean containInstance(String inst) {
		return instanceMap.containsKey(inst);
	}
	
	public boolean containConcept(String cncpt) {
		return conceptList.containsKey(cncpt);
	}
	
	public boolean canConceptualize(int instNum) {
		String typ = typical.get(instNum);
		return typ != null;
	}
	
	public int instanceIndex(String instName) {
		return instanceMap.get(instName);
	}
	
	public int conceptIndex(String conName) {
		return conceptList.get(conName);
	}
	
	/** need some modification */
	public String instanceTypical(int instNum) {
		String ans = typical.get(instNum);
		if (ans != null) {
			return ans;
		} else return "";
	}
	
	public void readAll() {
		timeStart();
		readInstance(instancePath);
		readConcept(conceptPath);
		readTypical(typicalPath);
	}
	
	public String info() {
		String ans =	"======= Information of the Parser ==========\n";
		ans += 			"1. Instance number: " + instanceMap.size() + "\n";
		ans += 			"2. Concept  number: " + conceptList.size() + "\n";
		ans += 			"3. Typical  number: " + typical.size()     + "\n";
		ans +=      	"============================================";
		return ans;
	}
	public String toString() {
		return this.info();
	}
	
	public void readConcept() {
		timeStart();
		this.readConcept(conceptPath);
	}
	private void readConcept(String conPath) {
		try {
			FileInputStream fis = new FileInputStream(conPath);
			DataInputStream dis = new DataInputStream(fis);
			BufferedReader br = new BufferedReader(new InputStreamReader(dis));
			String line = br.readLine();
			int count = 1;
			while (line != null && !line.equals("")) {
				conceptList.put(line, count);
				if (count % 1000000 == 0) {
					System.out.print(count + " c: ");
					time();
				}
				line = br.readLine();
				count++;
			}
			br.close();
			System.out.println(conceptList.size());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void readInstance() {
		timeStart();
		this.readInstance(instancePath);
	}
	private void readInstance(String insPath) {
		try {
			FileInputStream fis = new FileInputStream(insPath);
			DataInputStream dis = new DataInputStream(fis);
			BufferedReader br = new BufferedReader(new InputStreamReader(dis));
			String line = br.readLine();
			int count = 1;
			while (line != null && !line.equals("")) {
				instanceMap.put(line, count);
				if (count % 1000000 == 0) {
					System.out.print(count + " i: ");
					time();
				}
				line = br.readLine();
				count++;
			}
			br.close();
			System.out.println(instanceMap.size());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void readTypical() {
		timeStart();
		this.readTypical(typicalPath);
	}
	private void readTypical(String typPath) {
		try {
			FileInputStream fis = new FileInputStream(typPath);
			DataInputStream dis = new DataInputStream(fis);
			BufferedReader br = new BufferedReader(new InputStreamReader(dis));
			String line = br.readLine();
			int count = 1;
			while (line != null && !line.equals("")) {
				String[] tmp = line.split("\\t");
				if (!tmp[1].equals("0")) {
					int conIndex = Integer.parseInt(tmp[0]);
					int num = 0;
					num = Integer.parseInt(tmp[1]);
					String typ = "";
					for (int i = 0; i < num; i++) { 
						if (i == 0) typ += br.readLine();
						else if (i < 20) // TODO for now support top 20 conceptualization
							typ += "\t" + br.readLine();
						else 
							br.readLine(); // abandon other lines
					}
					typical.put(conIndex, typ);
				}
				if (count % 1000000 == 0) {
					System.out.print(count + " t: ");
					time();
				}
				line = br.readLine();
				count++;
			}
			br.close();
			System.out.println(typical.size());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private long startTimestamp, lastTimestamp;
	private void timeStart() {
		startTimestamp = System.currentTimeMillis();
		lastTimestamp = startTimestamp;
	}
	private void time() {
		long now = System.currentTimeMillis();
		System.out.print((now - lastTimestamp)/1000 + "s since last time;  ");
		System.out.println((now - startTimestamp)/1000 + "s since begin;  ");
		lastTimestamp = now;
	}
}
